package com.wh.minihelp.weixin.service;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.UUID;

import com.wh.lang.LogicException;
import com.wh.net.http.HttpClientUtil;
import com.wh.web.util.lang.StringUtil;
import com.wh.web.util.log.Logs;

public class WeixinContext {
	private static final String APPID = "您的ID";
	private static final String APPSECRET = "您的密钥";
	private final static String URL_ACCESS_TOKEN = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential" + "&appid=" + APPID + "&secret=" + APPSECRET;
	private final static String URL_JS_TICKET = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=";
	private final static long js_timerstamp = System.currentTimeMillis() / 1000;
	private final static String js_nonce = UUID.randomUUID().toString();
	private static final long PERIOD = 2 * 60 * 60 * 1000 - 10 * 1000;// 略小于2小时
	private static PeriodKey access_token = null;
	private static PeriodKey js_ticked = null;

	// private static HttpClient hc = null;
	private static class PeriodKey {
		private long preRefresh = 0, now = 0;
		private String key;
		private String value;
		private String url;

		public String getValue() {
			System.out.println("getv=====" + url);
			now = System.currentTimeMillis();
			if (now - preRefresh > PERIOD) {// 按时间检查需要重新刷新（使用Timer不太保险，有时SAE会给停掉，所以直接每次检查时间吧）
				try {
					String rtn = HttpClientUtil.executeRequest(null, url);
					String[] params = StringUtil.toArray(rtn, "}{:,\"", false);
					for (int i = 0; i < params.length;) {
						String pk = params[i];
						if (key.equals(pk)) {
							value = params[i + 1];
							preRefresh = System.currentTimeMillis();
							break;
						}
						i = i + 2;// 每次跳俩个
					}
					System.out.println("\t real=====" + url);
				} catch (Throwable e) {
					Logs.println("获取【" + url + "】出错了!");
					Logs.println(e);
					e.printStackTrace();
					value = null;
				}
			}
			return value;
		}
	}

	public final static String getAppId() {
		return APPID;
	}

	// 获取AccessToken
	public final static String getAccessToken() {
		if (access_token == null) {
			access_token = new PeriodKey();
			access_token.key = "access_token";
			access_token.url = URL_ACCESS_TOKEN;
		}
		return access_token.getValue();
	}

	public final static String getJSTicket() {
		if (js_ticked == null) {
			js_ticked = new PeriodKey();
			js_ticked.key = "ticket";
		}
		js_ticked.url = URL_JS_TICKET + getAccessToken();// 此url可能会发生变化
		return js_ticked.getValue();
	}

	public final static String getJSNoncestr() {
		// return "wx_minihelp_jsticket";
		return js_nonce;
	}

	public final static long getJSTimestamp() {
		return js_timerstamp;
	}

	public final static String getJSSignature(String url) {
		try {
			String orignial = "jsapi_ticket=" + getJSTicket() //
					+ "&noncestr=" + getJSNoncestr()//
					+ "&timestamp=" + getJSTimestamp() //
					+ "&url=" + url;
			System.out.println("orignial = " + orignial);
			return signature(orignial);
		} catch (Throwable e) {
			throw new LogicException("程序内部错误（JS初始化问题？）！", e);
		}
	}

	public static String signature(String original) throws NoSuchAlgorithmException, UnsupportedEncodingException {
		MessageDigest crypt = MessageDigest.getInstance("SHA-1");
		crypt.reset();
		crypt.update(original.getBytes("UTF-8"));
		return byteToHex(crypt.digest());
	}

	private static String byteToHex(final byte[] hash) {
		Formatter formatter = new Formatter();
		for (byte b : hash) {
			formatter.format("%02x", b);
		}
		String result = formatter.toString();
		formatter.close();
		return result;
	}


}
